package com.atguigu.juc.future;

import java.util.concurrent.*;

/**
 * @Description: CompletableFuture API
 * @author： yeswater
 * @create： 2024/5/29
 */

public class CompletableFutureApiDemo {
	public static void main(String[] args) {
		//part1();
		//part2();
		//part3();
		part4();
	}
	
	/* 获取结果 */
	private static void part1() {
		CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
			return "abc";
		});
		
		//System.out.println(completableFuture.get()); //阻塞 需要抛异常
		//System.out.println(completableFuture.get(2L, TimeUnit.SECONDS)); // 指定时间
		//System.out.println(completableFuture.join()); // 阻塞 不需要抛异常
		//System.out.println(completableFuture.getNow("xxx")); // 立刻返回 正常值|备胎值
	}
	
	/**
	 * 对结果进行处理
	 * thenApply --->计算结果存在依赖关系，这两个线程串行化---->由于存在依赖关系（当前步错，不走下一步），当前步骤有异常的话就叫停
	 * handle --->计算结果存在依赖关系，这两个线程串行化---->有异常也可以往下走一步
	 */
	private static void part2() {
		ExecutorService threadPool = Executors.newFixedThreadPool(3);
		CompletableFuture.supplyAsync(() -> {
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return 1;
		}, threadPool).thenApply(f -> {
			System.out.println("222");
			return f + 2;
		}).handle((f, e) -> {
			System.out.println("3333");
			int i = 10 / 0;
			return f + 2;

//             thenApply(f -> {
//            System.out.println("3333");
//            return f + 2;
		}).whenComplete((v, e) -> {
			if (e == null) {
				System.out.println("----计算结果" + v);
			}
		}).exceptionally(e -> {
			e.printStackTrace();
			System.out.println(e.getCause());
			return null;
		});
		System.out.println(Thread.currentThread().getName() + "------主线程先去做其他事情");
	}
	
	/**
	 * 对计算结果进行消费
	 */
	private static void part3() {
		ExecutorService threadPool = Executors.newFixedThreadPool(3);
		CompletableFuture.supplyAsync(() -> {
			return 1;
		}, threadPool).thenApply(v -> {
			return v + 1;
		}).thenApply(v -> {
			return v + 2;
		}).thenAccept(v -> {
			System.out.println(v);
		});
		
	}
	
	/**
	 * 对比补充
	 * <p>
	 * ■ thenRun(Runnable runnable) :任务A执行完执行B，并且不需要A的结果
	 * ■ thenAccept(Consumer action): 任务A执行完执行B，B需要A的结果，但是任务B没有返回值
	 * ■ thenApply(Function fn): 任务A执行完执行B，B需要A的结果，同时任务B有返回值
	 */
	private static void part4() {
		System.out.println(Thread.currentThread().getName() + " " + CompletableFuture.supplyAsync(() -> "result")
				                                                      .thenRun(() -> {}).join());//null
		System.out.println();
		System.out.println(Thread.currentThread().getName() + " " + CompletableFuture.supplyAsync(() -> "result")
				                                                      .thenAccept(r -> System.out.println(Thread.currentThread().getName() +  " " + r)).join());//result null
		System.out.println();
		System.out.println(Thread.currentThread().getName() + " " + CompletableFuture.supplyAsync(() -> "result")
				                                                      .thenApply(f -> f + 2).join());//result2
	}
}

